﻿using IdentityServer3.Core;
using IdentityServer3.Core.Configuration;
using IdentityServer3.Core.Models;
using IdentityServer3.Core.Services;
using Microsoft.IdentityModel.Protocols;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using System.Web;
using System.Web.Helpers;
using Serilog;

[assembly: OwinStartup(typeof(EmbeddedMVC.Startup))]
namespace EmbeddedMVC
{
    public class Startup
    {
        private static string redirecturl = System.Configuration.ConfigurationManager.AppSettings["RedirectUri"].ToString();
        public void Configuration(IAppBuilder app)
        {
            Log.Logger = new LoggerConfiguration()
              .MinimumLevel.Debug()
              .WriteTo.File(string.Format(@"{0}\logs\identity.txt", AppDomain.CurrentDomain.BaseDirectory))
              .CreateLogger();

            AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject;
            JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "Cookies"
            });
            //配置identityserver服务器，包括用户，客户端
            app.Map("/identity", idsrvApp =>
             {
                 var factory = new IdentityServerServiceFactory()
                     .UseInMemoryClients(CustomClients.Get())
                     .UseInMemoryScopes(Scopes.Get());

                 //自定义登录
                 factory.UserService = new Registration<IUserService, CustomLoginPageUserService>();

                 var options = new IdentityServerOptions
                 {
                     SiteName = "阿卡索单点登录",

                     SigningCertificate = LoadCertificate(),
                     RequireSsl = false,//去除ssl限制
                     Factory = factory,

                     //设置登出参数
                     AuthenticationOptions = new IdentityServer3.Core.Configuration.AuthenticationOptions
                     {
                         EnableSignOutPrompt = false,
                         EnablePostSignOutAutoRedirect = true,
                         PostSignOutAutoRedirectDelay =0
                     }
                 };

                 idsrvApp.UseIdentityServer(options);
             });


            //配置本地客户端
            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                //Authority = redirecturl+"identity",
                Authority = redirecturl + "identity",
                ClientId = "mvc",
                Scope = "openid profile roles",
                RedirectUri = redirecturl,
                ResponseType = "id_token",

                SignInAsAuthenticationType = "Cookies",

                UseTokenLifetime = false,

                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    SecurityTokenValidated = n =>
                    {
                        var id = n.AuthenticationTicket.Identity;

                        // we want to keep first name, last name, subject and roles
                        var givenName = id.FindFirst(Constants.ClaimTypes.GivenName);
                        var familyName = id.FindFirst(Constants.ClaimTypes.FamilyName);
                        var sub = id.FindFirst(Constants.ClaimTypes.Subject);
                        var roles = id.FindAll(Constants.ClaimTypes.Role);

                        // create new identity and set name and role claim type
                        //var nid = new ClaimsIdentity(
                        //    id.AuthenticationType,
                        //    Constants.ClaimTypes.GivenName,
                        //    Constants.ClaimTypes.Role);

                        //nid.AddClaim(givenName);
                        //nid.AddClaim(familyName);
                        //nid.AddClaim(sub);
                        //nid.AddClaims(roles);

                        var nid = new ClaimsIdentity(id);

                        // add some other app specific claim
                        //nid.AddClaim(new Claim("app_specific", "some data"));

                        //id_token
                        //nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));

                        n.AuthenticationTicket = new AuthenticationTicket(
                            nid,
                            n.AuthenticationTicket.Properties);

                        return Task.FromResult(0);
                    },


                    RedirectToIdentityProvider = n =>
                    {
                        if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
                        {
                            var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

                            if (idTokenHint != null)
                            {
                                n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                            }
                        }

                        return Task.FromResult(0);
                    }
                }


            });

            app.UseResourceAuthorization(new AuthorizationManager());
        }

        X509Certificate2 LoadCertificate()
        {
            return new X509Certificate2(
                string.Format(@"{0}\Certificates\idsrv3test2.pfx", AppDomain.CurrentDomain.BaseDirectory), "idsrv3test");
        }
    }
}